package com.aner.tester.generator.param;

import com.aner.tester.generator.TypeManager;
import com.aner.tester.generator.data.ValueGenerator;
import com.aner.tester.object.MethodObject;
import com.aner.tester.object.ValueObject;
import org.springframework.cglib.beans.BeanGenerator;
import org.springframework.cglib.beans.BeanMap;

import java.util.List;

/**
 * the payload method of parameter generator
 *
 * @author aner
 * @version 1.0
 * @date 2020/12/13 10:19
 */
public class PayloadGenerator extends ParameterGenerator {

    /**
     * dynamic object
     */
    private Object object;

    /**
     * field map
     */
    private BeanMap beanMap;

    /**
     * method data object
     */
    private MethodObject methodObject;

    public PayloadGenerator(MethodObject methodObject) {
        this.methodObject = methodObject;

    }


    @Override
    public Object generate() {
        object = this.generateObject();
        beanMap = BeanMap.create(object);
        generateValue();
        return object == null ? new Object(): object;

    }

    protected Object generateObject() {

        List<ValueObject> valueObjectList = methodObject.getValueObjects();
        BeanGenerator generator = new BeanGenerator();
        for(ValueObject valueObject: valueObjectList) {

            Class<?> cls = TypeManager.getTypeClass(valueObject);
            if (cls != null) {
                generator.addProperty(valueObject.getName(), cls);
            } else {
                logger.error("{} is not existed", valueObject.getTypeName());
            }
        }
        return generator.create();
    }

    @Override
    protected void generateValue() {

        List<ValueObject> valueObjectList = methodObject.getValueObjects();

        if (valueObjectList.size() == 1) {
            // custom object
            ValueObject valueObject = valueObjectList.get(0);
            valueObject.setLevelCount(0);
            this.object = ValueGenerator.generate(valueObject);
            return;
        }

        for(ValueObject valueObject: valueObjectList) {
            Object value = ValueGenerator.generate(valueObject);
            setValue(valueObject.getName(), value);
        }
    }

    /**
     * set value
     *
     * @param property
     * @param value
     */
    public PayloadGenerator setValue(Object property, Object value) {
        beanMap.put(property, value);
        return this;
    }

    /**
     * get value
     *
     * @param property
     * @return 值
     */
    public Object getValue(String property) {
        return beanMap.get(property);
    }

    /**
     * get object
     *
     * @return
     */
    public Object getObject() {
        return this.object;
    }

}
